using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading.Tasks;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace PdfOperationCommand
{
    [Icon("pack://application:,,,/PdfOperationCommand;component/Resources/Rotate.png")]
    [OrderWeight(4)]
    [Description("旋转PDF文件，使用iTextSharp实现")]
    public class PdfRotationServerCommand : BaseServerCommand, ICommandExecutableInServerSideAsync
    {
        [Required]
        [FormulaProperty]
        [DisplayName("文件路径")]
        [Description("文件绝对路径，如：D:\\example.pdf(Windows)，/path/example.pdf(Linux)")]
        public object FilePath { get; set; }

        [DisplayName("PDF文件旋转类型")]
        [Description("PDF文件旋转类型")]
        public PdfRotationType PdfRotationType { get; set; }

        [Required]
        [FormulaProperty]
        [DisplayName("输出文件路径")]
        [Description("文件绝对路径，如：D:\\example.pdf(Windows)，/path/example.pdf(Linux)")]
        public object OutFilePath { get; set; }

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var filePath = await GetParamValue(dataContext, FilePath);
            var outFilePath = await GetParamValue(dataContext, OutFilePath);

            using var reader = new PdfReader(filePath.ToString());
            switch (PdfRotationType)
            {
                case PdfRotationType.Clockwise90:
                    RotatePdf(reader, outFilePath.ToString(), 90);
                    break;
                case PdfRotationType.Counterclockwise90:
                    RotatePdf(reader, outFilePath.ToString(), -90);
                    break;
                case PdfRotationType.Flip180:
                    RotatePdf(reader, outFilePath.ToString(), 180);
                    break;
                default:
                    RotatePdf(reader, outFilePath.ToString(), 90);
                    break;
            }

            return new ExecuteResult();
        }

        private void RotatePdf(PdfReader reader, string outputPath, int rotationAngle)
        {
            using var doc = new Document();
            using var writer = new PdfCopy(doc, new FileStream(outputPath, FileMode.Create));
            doc.Open();
            for (var page = 1; page <= reader.NumberOfPages; page++)
            {
                var rotation = reader.GetPageRotation(page);
                var pageDict = reader.GetPageN(page);
               
                pageDict.Put(PdfName.ROTATE, new PdfNumber(rotation + rotationAngle));
                var importedPage = writer.GetImportedPage(reader, page);
                writer.AddPage(importedPage);
            }
        }

        public override string ToString()
        {
            return "旋转PDF文件";
        }
    }

    public enum PdfRotationType
    {
        [Description("顺时针90°")] Clockwise90,
        [Description("逆时针90°")] Counterclockwise90,
        [Description("翻转180°")] Flip180
    }
}